#include <string>
#include <map>
#include <fstream>
#include <algorithm>
#include <iostream>
#include <vector>

namespace part1
{
    enum class Instruction
    {
        LEFT,
        RIGHT,
    };

    class Network
    {
        using Nexts = std::pair<std::string, std::string>;

    public:
        Network(std::ifstream& file) : _paths{}
        {
            std::string line;

            while (std::getline(file, line))
            {
                std::string node {line.substr(0, 3)};

                std::size_t leftNodeIdx {line.find('(') + 1};
                std::string leftNode {line.substr(leftNodeIdx, 3)};
                
                std::size_t rightNodeIdx {line.find(',') + 2};
                std::string rightNode {line.substr(rightNodeIdx, 3)};

                this->_paths.emplace(
                    std::move(node), std::make_pair(std::move(leftNode), std::move(rightNode))
                );
            }
        }

    public:
        std::size_t getStepSize(const std::vector<Instruction>& instructions, 
                                const std::string& beginNode = "AAA",
                                const std::string& targetNode = "ZZZ")
        {
            std::size_t stepSize {0};
            std::string currentNode {beginNode};
            while (true)
            {
                for (Instruction ins : instructions)
                {
                    if (currentNode == targetNode)
                        return stepSize;

                    Nexts& next {this->_paths[currentNode]};
                    currentNode = ins == Instruction::LEFT ? next.first : next.second;
                    stepSize += 1;
                }
            }
        }

        void print() const
        {
            for (const auto& path : this->_paths)
            {
                std::cout << path.first << " => "
                          << '(' << path.second.first << ','
                          << ' ' << path.second.second << ')' << std::endl;
            }
        }

    private:
        std::map<std::string, Nexts> _paths;
    };

    std::vector<Instruction> getInstructions(const std::string& line)
    {
        std::vector<Instruction> instructions{};
        for (const char ch : line)
            instructions.emplace_back(ch == 'L' ? Instruction::LEFT : Instruction::RIGHT);
        return instructions;
    }

    void solute()
    {
        std::ifstream file {"./src/day08/input.txt"};
        std::string line;
        std::getline(file, line);

        std::vector<Instruction> instructions {getInstructions(line)};
        std::getline(file, line);

        Network network {file};
        // network.print();

        std::cout << network.getStepSize(instructions, "AAA", "ZZZ") << std::endl;
    }
}
